/**
 @file ctc_nexthop_fp.h

 @date 2022-04-20

 @version v2.0

*/
#ifndef _CTC_NEXTHOP_FP_H_
#define _CTC_NEXTHOP_FP_H_
#ifdef __cplusplus
extern "C" {
#endif

/*Move flex edit API to sys layer*/
/**
 @brief  Define flexible programing edit type {ins/del/rep}
*/
enum ctc_nh_fp_edit_type_e
{
   CTC_NH_FP_EDIT_INS,   /**< [TMM.AT] insert a segment of packet, and support replace some field*/
   CTC_NH_FP_EDIT_DEL,   /**< [TMM.AT] delete a segment of packet, and support replace some field*/
   CTC_NH_FP_EDIT_REP    /**< [TMM.AT] replace some field of the packet*/
};
typedef enum ctc_nh_fp_edit_type_e ctc_nh_fp_edit_type_t;

/**
 @brief  Define flexible programing data type
*/
enum ctc_nh_fp_data_type_e
{
   CTC_NH_FP_DATA_RAW,               /**< [TMM.AT] raw data, for use define data*/
   CTC_NH_FP_DATA_PACKET,            /**< [TMM.AT] data extract from in packet*/
   CTC_NH_FP_DATA_SRC_PORT,          /**< [TMM.AT] use source global port*/
   CTC_NH_FP_DATA_DST_PORT,          /**< [TMM.AT] use dest global port*/
   CTC_NH_FP_DATA_SRC_LPORT,         /**< [TMM.AT] use source local port*/
   CTC_NH_FP_DATA_DST_LPORT,         /**< [TMM.AT] use dest local port*/
   CTC_NH_FP_DATA_HASH_VALUE,        /**< [TMM.AT] use hash value*/
   CTC_NH_FP_DATA_QUEUE_ID,          /**< [TMM.AT] use queue id*/
   CTC_NH_FP_DATA_L3_PROTOCOL,       /**< [TMM.AT] use l3 header protocol*/
   CTC_NH_FP_DATA_SRC_VLAN_PTR,      /**< [TMM.AT] use source vlan ptr*/
   CTC_NH_FP_DATA_L3_INTF,           /**< [TMM.AT] use dest l3 interface id*/
   CTC_NH_FP_DATA_LOGIC_SRC_PORT,    /**< [TMM.AT] use logic source port*/
   CTC_NH_FP_DATA_LOGIC_DST_PORT,    /**< [TMM.AT] use logic dest port*/
   CTC_NH_FP_DATA_QUEUE_DEPTH,       /**< [TMM.AT] use queue depth*/
   CTC_NH_FP_DATA_SPAN_ID,           /**< [TMM.AT] use span id*/
   CTC_NH_FP_DATA_FLEX_LEN,          /**< [TMM.AT] flex length from ingress scl*/
   CTC_NH_FP_DATA_TTL,               /**< [TMM.AT] use packet ttl*/
   CTC_NH_FP_DATA_IP_LEN,            /**< [TMM.AT] use packet ip length*/
   CTC_NH_FP_DATA_LOAD_METRIC,       /**< [TMM.AT] use Load metric*/
   CTC_NH_FP_DATA_LATENCY,           /**< [TMM.AT] use packet latency*/
   CTC_NH_FP_DATA_TS_HIGH,           /**< [TMM.AT] use timestamp high bits*/
   CTC_NH_FP_DATA_TS_LOW,            /**< [TMM.AT] use timestamp low bits*/
   CTC_NH_FP_DATA_IGS_TS,            /**< [TMM.AT] use ingress timestamp*/
   CTC_NH_FP_DATA_EGS_TS,            /**< [TMM.AT] use egress timestamp*/
   CTC_NH_FP_DATA_IGS_TS_HIGH,       /**< [TMM.AT] use ingress timestamp high*/
   CTC_NH_FP_DATA_IGS_TS_LOW,        /**< [TMM.AT] use ingress timestamp low*/

   CTC_NH_FP_DATA_FID,                  /**< [AT] select fid, for stage2*/
   CTC_NH_FP_DATA_VNI_ID,               /**< [AT] 8/16/24 bits vni are supported, use len to specify which length to choose, for stage2*/
   CTC_NH_FP_DATA_SRC_CID,              /**< [AT] 8/16 bits src cid are supported, use len to specify which length to choose, for stage2*/
   CTC_NH_FP_DATA_L4_SRC_PORT_LOW,      /**< [AT] select l4 source port low 8 bits for TCP/UDP/ICMP packet, for stage2*/
   CTC_NH_FP_DATA_L4_SRC_PORT_HIGH,     /**< [AT] select l4 source port high 8 bits for TCP/UDP/ICMP packet, for stage2*/
   CTC_NH_FP_DATA_L4_DST_PORT_LOW,      /**< [AT] select l4 dest port low 8 bits for TCP/UDP packet, for stage2*/
   CTC_NH_FP_DATA_L4_DST_PORT_HIGH,     /**< [AT] select l4 dest port high 8 bits for TCP/UDP packet, for stage2*/
   CTC_NH_FP_DATA_PRI_COLOR,            /**< [AT] select priority and color, for stage2*/
   CTC_NH_FP_DATA_l3_TYPE,              /**< [AT] select l3 type, refer to ctc_parser_l3_type_t, for stage2*/
   CTC_NH_FP_DATA_ESLB,                 /**< [AT] select Es Label, for stage2*/
   CTC_NH_FP_DATA_XDATA,                /**< [AT] select a piece of XDATA, use len to specify the length, use src_offset to specify the position, for stage2*/
};
typedef enum ctc_nh_fp_data_type_e ctc_nh_fp_data_type_t;

/**
 @brief  Define flexible programing zone
*/
enum ctc_nh_fp_zone_e
{
   CTC_NH_FP_ZONE_PACKET,      /**< [TMM.AT] alias zone 0, default for fp operate on packet zone*/
   CTC_NH_FP_ZONE_INS_DATA     /**< [TMM.AT] alias zone 1, default for fp operate on insert data zone*/
};
typedef enum ctc_nh_fp_zone_e ctc_nh_fp_zone_t;

/**
 @brief  Define flexible programing operator
*/
enum ctc_nh_fp_op_e
{
   CTC_NH_FP_OP_NOP,    /**< [TMM.AT] do no opreator*/
   CTC_NH_FP_OP_GT,     /**< [TMM.AT] operator >*/
   CTC_NH_FP_OP_GE,     /**< [TMM.AT] operator >=*/
   CTC_NH_FP_OP_LT,     /**< [TMM.AT] operator <*/
   CTC_NH_FP_OP_LE,     /**< [TMM.AT] operator <=*/
   CTC_NH_FP_OP_EQ,     /**< [TMM.AT] operator =*/
   CTC_NH_FP_OP_NE,     /**< [TMM.AT] operator !=*/
   CTC_NH_FP_OP_ADD,    /**< [TMM.AT] operator +*/
   CTC_NH_FP_OP_SUB,    /**< [TMM.AT] operator -*/
   CTC_NH_FP_OP_SHL,    /**< [TMM.AT] operator <<*/
   CTC_NH_FP_OP_SHR,    /**< [TMM.AT] operator >>*/
   CTC_NH_FP_OP_ROL,    /**< [TMM.AT] operator <<(ROL)*/
   CTC_NH_FP_OP_ROR     /**< [TMM.AT] operator >>(ROR)*/
};
typedef enum ctc_nh_fp_op_e ctc_nh_fp_op_t;

/**
 @brief  Define flexible programing field data
*/
struct ctc_nh_fp_data_s
{
    uint8 type;          /**< [TMM.AT] data type, refer to ctc_nh_fp_data_type_t*/
    uint8 len;           /**< [TMM.AT] operator data length, Uints:bits*/
    uint8 shift;         /**< [TMM.AT] operator data shift (data left shift bits), Uints: bits*/
    uint8 src_offset;    /**< [AT]  selected source offset for 128 bits XDATA, Uints: bits, for stage2*/

    uint32 mask;      /**< [TMM.AT] operator data mask, Uints: bits*/
    uint32 value;     /**< [TMM.AT] value when data type use CTC_NH_FP_DATA_RAW*/
};
typedef struct ctc_nh_fp_data_s ctc_nh_fp_data_t;

/**
 @brief  Define flexible programing field check condition
*/
struct ctc_nh_fp_field_chk_s
{
    uint8 chk_op;     /**< [TMM.AT] check oprerator, refore to ctc_nh_fp_op_t, only support CTC_NH_FP_OP_GT/LT/EQ/NE/GE/LE**/
    uint8 discard;    /**< [TMM.AT] check opeartion and discard the packet*/
    uint8 to_cpu;     /**< [TMM.AT] check opeartion copy or redirect to cpu*/
    uint8 rsv;

};
typedef struct ctc_nh_fp_field_chk_s ctc_nh_fp_field_chk_t;

/**
 @brief  Define flexible programing field
*/
struct ctc_nh_fp_field_s
{
    uint16 offset;            /**< [TMM.AT] edit zone field offset, Unit: bits*/
    uint8 len;                /**< [TMM.AT] edit zone field length, max is 32bits, Unit:bits*/
    uint8 zone;               /**< [TMM.AT] edit zone, refer to ctc_nh_fp_zone_t*/
    uint8 data_op;            /**< [TMM.AT] data operator, data (oprerator +/-) data_r, refer to ctc_nh_fp_op_t*/
    uint8 zone_op;            /**< [TMM.AT] zone operator,(oprerator +/-) with packet or ins data, refer to ctc_nh_fp_op_t*/
    uint8 result_shift;       /**< [TMM.AT] data operator result shift (shift right), Uint:bits*/
    uint8 rsv;
    ctc_nh_fp_data_t data;    /**< [TMM.AT] field data, if use alu, use as data_operator left value*/
    ctc_nh_fp_data_t data_r;  /**< [TMM.AT] field data which use as data_operator right value*/
    ctc_nh_fp_field_chk_t chk;     /**< [TMM.AT] data operator check which packet will be drop or to cpu*/
};
typedef struct ctc_nh_fp_field_s ctc_nh_fp_field_t;


/**
 @brief  Define flexible programing chksum field
*/
struct ctc_nh_fp_chksum_s
{
    uint8 enable;            /**< [TMM.AT] update checksum enable*/
    uint8 offset;            /**< [TMM.AT] checksum offset from l3 or l4, if offset == 0xFF, offset will auto cal, uint:Bytes*/
    uint8 extra_update;      /**< [TMM.AT] insert/del header update enable*/
    uint8 rsv;
    uint32 mask;            /**< [TMM.AT] mask bitmap which 1 bit be regard as 4bit packet length*/
};
typedef struct ctc_nh_fp_chksum_s ctc_nh_fp_chksum_t;


#define CTC_NH_FP_FIELD_MAX 16
enum ctc_nh_fp_flag_e
{
   CTC_NH_FP_FLAG_STAGE2        = 0x00000001,      /**< [AT] If set, means this fp used for stage 2*/
   CTC_NH_FP_FLAG_KEEP_L3_LEN   = 0x00000002,      /**< [AT] Keep packet's L3 len unchange*/
   CTC_NH_FP_FLAG_KEEP_L4_LEN   = 0x00000004,      /**< [AT] Keep packet's L4 len unchange*/
   CTC_NH_FP_FLAG_WITHOUT_TMP   = 0x00000008,      /**< [AT] If set, not use insert template for CTC_NH_FP_EDIT_INS*/
   CTC_NH_FP_FLAG_REP_SEL_VALID = 0x00000010       /**< [AT] If set, config replace data base original pkt or insert pkt by repalce_sel field*/
};
typedef enum ctc_nh_fp_flag_e ctc_nh_fp_flag_t;

/**
 @brief  Define flexible programing edit structure
*/
struct ctc_nh_fp_edit_s
{
    uint32 fp_id;             /**< [TMM.AT]  fp id, if set 0, return id by SDK*/
    uint32 flag;              /**< [TMM.AT]  flags refer to ctc_nh_fp_flag_t*/
    uint8 edit_type;          /**< [TMM.AT] edit type, refer to ctc_nh_fp_edit_type_t*/

    uint8 offset_type;        /**< [TMM.AT] edit offset type, refer to ctc_pkt_offset_type_t*/
    uint8 offset;             /**< [TMM.AT] edit offset from offset_type, uint:Bytes*/
    uint8 use_outer;          /**< [AT] if set, means offset based on outer head*/

    /*update checksum*/
    ctc_nh_fp_chksum_t l3chksum; /**< [TMM.AT] layer3 checksum update*/
    ctc_nh_fp_chksum_t l4chksum; /**< [TMM.AT] layer4 checksum update*/

    uint32 next_fp_id;         /**< [AT] Append the stage 2 flexible program edit id*/

    /*replace opreation*/
    uint8 offset_type_ext;     /**< [TMM.AT] edit offset type, for extra packet modify*/
    uint8 offset_ext;          /**< [TMM.AT] edit offset for extra packet modify from offset_type_ext, unit:Bytes*/
    uint8 ext_use_outer;       /**< [AT] if set, means offset_ext based on outer head*/

    uint8 field_cnt;                   /**< [TMM.AT] Flexiable field list cnt for CTC_NH_FP_EDIT_REP or insert/delete append replace operation*/
    ctc_nh_fp_field_t* p_field_list;   /**<[TMM.AT] operate field array*/

    uint8 replace_sel;                /**<[TMM.AT] if set, replace data based on insert pkt else on original pkt, bit 0 for zone 0, bit 1 for zone1*/

    /*insert opreation*/
    uint8 len;                /**< [TMM.AT] edit length which use for insert or delete, unit: Bytes */
    uint8 *data;              /**< [TMM.AT] raw data which use for insert*/

    /*delete opreation lenth*/
    uint8 len_from_data;        /**< [TMM.AT] if set means del length from ctc_nh_fp_data_t*/
    ctc_nh_fp_data_t length;    /**< [TMM.AT] Delete length from ctc_nh_fp_data_t*/
};
typedef struct ctc_nh_fp_edit_s ctc_nh_fp_edit_t;

/**
 @brief  Define flexible program edit flags
*/
enum ctc_misc_nh_fp_flag_e
{
    CTC_MISC_NH_FP_FLAG_OP_BRIDGE = 0x0001, /**< [TMM.AT] Flex program do bridge opreation */
    CTC_MISC_NH_FP_FLAG_REBACK    = 0x0002, /**< [TMM.AT] If set, indicates that the packets will loopback to source port */
    CTC_MISC_NH_FP_FLAG_MTU_NO_CHK= 0x0004, /**< [TMM.AT] if set, Disable MTU check, default enable MTU check */
    CTC_MISC_NH_FP_FLAG_REPLACE_L2HDR = 0x0008 /**< [TMM.AT] If set, indicates replace L2 header*/
};
typedef enum ctc_misc_nh_fp_flag_e ctc_misc_nh_fp_flag_t;
/**
 @brief  Define flexible program edit parameter structure
*/
struct ctc_misc_nh_fp_edit_param_s
{
    uint32 fp_id;    /**< [TMM.AT] nexthop flex program  id */
    uint16 span_id;  /**< [TMM.AT] span id which used for fp edit */
    uint16 flag;     /**< [TMM.AT] flex program flag, refer to ctc_misc_nh_fp_flag_t */
};
typedef struct ctc_misc_nh_fp_edit_param_s ctc_misc_nh_fp_edit_param_t;


/*#endif*/
#ifdef __cplusplus
}
#endif

#endif /*_CTC_NEXTHOP_FP_H_*/

